package com.example.net

import com.alibaba.android.arouter.launcher.ARouter
import com.blankj.utilcode.util.EncryptUtils
import com.example.base.RoutePath
import com.tencent.mmkv.MMKV
import okhttp3.Interceptor
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import okhttp3.ResponseBody.Companion.toResponseBody
import okhttp3.logging.HttpLoggingInterceptor
import okio.Buffer
import org.json.JSONObject
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.sql.Time
import java.util.concurrent.TimeUnit

object HttpManager {

    private fun getOKHttpClient(type: HttpInterceptorType):OkHttpClient{
        var okBuilder = OkHttpClient.Builder()
        if(BuildConfig.isOpenLog){
            okBuilder.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
        }
        okBuilder.connectTimeout(5,TimeUnit.MINUTES)
        okBuilder.readTimeout(5,TimeUnit.MINUTES)
        okBuilder.writeTimeout(5,TimeUnit.MINUTES)
        when(type){
            HttpInterceptorType.SIGN -> {
                okBuilder.addInterceptor(getSignInterceptor())
            }
            HttpInterceptorType.UPLOAD->{
                okBuilder.writeTimeout(3,TimeUnit.MINUTES)
                okBuilder.readTimeout(3,TimeUnit.MINUTES)
            }
            HttpInterceptorType.TOKEN->{
                okBuilder.addInterceptor(getTokenInterceptor())
            }
            HttpInterceptorType.INTERCEPTOR->{
//                okBuilder.addInterceptor(getSignInterceptor())
//                okBuilder.addInterceptor(getTokenInterceptor())
            }
        }
        okBuilder.addInterceptor(getErrorServerInterceptor())
        return okBuilder.build()
    }

    private fun getRetrofit(type:HttpInterceptorType):Retrofit{
        return Retrofit.Builder()
            .baseUrl(BuildConfig.BASE_URL)
            .client(getOKHttpClient(type))
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }

    private fun getErrorServerInterceptor(): Interceptor {
        return object :Interceptor{
            override fun intercept(chain: Interceptor.Chain): Response {
                var response = chain.proceed(chain.request())
                var builder = response.newBuilder()
                if(response.code == 500){
                    var newJson = JSONObject()
                    newJson.put("code",500)
                    newJson.put("msg","服务器接口异常，联系客服")
                    var body = newJson.toString().toResponseBody("application/json;charset=utf-8".toMediaTypeOrNull())
                    builder.body(body)
                }
                return builder.build()
            }

        }
    }

    private fun getTokenInterceptor(): Interceptor {
        return object :Interceptor{
            override fun intercept(chain: Interceptor.Chain): Response {
                val token = MMKV.defaultMMKV().decodeString("token")
                if(!token.isNullOrEmpty()){
                    var request = chain.request().newBuilder().header("token", token).build()
                    var proceed = chain.proceed(request)
                    if(proceed.code == 403){
                        ARouter.getInstance().build(RoutePath.ROUTE_LOGIN)
                    }
                    return proceed
                }
                return chain.proceed(chain.request())
            }
        }
    }

    private fun getMd5Encrypt(originStr: String): String {
        return EncryptUtils.encryptMD5ToString("${originStr}tamboo").lowercase()
    }

    private fun getSignInterceptor() :Interceptor{
        return object :Interceptor{
            override fun intercept(chain: Interceptor.Chain): Response {
                var request = chain.request()
                try {
                    var builder = request.newBuilder()
                    builder.url(request.url)
                    builder.headers(request.headers)
                    var buf = Buffer()
                    var reqBody = request.body
                    reqBody?.writeTo(buf)
                    var bodyStr = buf.toString()
                    buf.close()
                    bodyStr = bodyStr.substring(bodyStr.indexOf("{"),bodyStr.lastIndexOf("}")+1)
                    var jsonObject = JSONObject(bodyStr)

                    var sb = StringBuffer()
                    var keys = jsonObject.keys()
                    while (keys.hasNext()){
                        sb.append(jsonObject.getString(keys.next()))
                    }
                    var signMd5 = getMd5Encrypt(sb.toString())
                    jsonObject.put("sign",signMd5)

                    var newJson = jsonObject.toString()
                    var newBody = newJson.toRequestBody()
                    builder.post(newBody)

                    var newRequest = builder.build()
                    return chain.proceed(newRequest)
                }catch (e:Exception){
                    e.printStackTrace()
                    return chain.proceed(request)
                }
            }

        }
    }
    fun<T>createApiService(clazz: Class<*>,type: HttpInterceptorType):T{
        return getRetrofit(type).create(clazz) as T
    }
}